package edu.cmu.fithub.controller;

import java.io.IOException;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import edu.cmu.fithub.actions.AddFriendAction;
import edu.cmu.fithub.actions.CreateCommentAction;
import edu.cmu.fithub.actions.CreateGroupAction;
import edu.cmu.fithub.actions.CreateUserPostAction;
import edu.cmu.fithub.actions.DeleteFriendAction;
import edu.cmu.fithub.actions.DisplayFriendAction;
import edu.cmu.fithub.actions.DisplayGroupAction;
import edu.cmu.fithub.actions.DisplayGroupHomeAction;
import edu.cmu.fithub.actions.DisplayHomeAction;
import edu.cmu.fithub.actions.InviteMemberAction;
import edu.cmu.fithub.actions.JoinGroupAction;
import edu.cmu.fithub.actions.LeaveGroupAction;
import edu.cmu.fithub.actions.LoginAction;
import edu.cmu.fithub.actions.RegisterAction;
import edu.cmu.fithub.actions.SearchFriendAction;
import edu.cmu.fithub.actions.SearchGroupAction;
import edu.cmu.fithub.actions.SearchInviteMemberAction;
import edu.cmu.fithub.actions.ShowCommentAction;
import edu.cmu.fithub.actions.*;
import edu.cmu.fithub.actions.ShowInviteAction;
import edu.cmu.fithub.actions.ShowStoryAction;
import edu.cmu.fithub.db.bean.User;

public class Controller extends HttpServlet {

	private static final long serialVersionUID = 1L;

	public void init() throws ServletException {

		Action.add(new RegisterAction());
		Action.add(new LoginAction());
		Action.add(new RegisterOpenIdAction());
		Action.add(new DisplayHomeAction());
		Action.add(new DisplayFriendAction());
		Action.add(new AddFriendAction());
		Action.add(new SearchFriendAction());
		Action.add(new DeleteFriendAction());
		Action.add(new CreateGroupAction());
		Action.add(new DisplayGroupAction());
		Action.add(new SearchGroupAction());
		Action.add(new JoinGroupAction());
		Action.add(new LeaveGroupAction());
		Action.add(new CreateUserPostAction());
		Action.add(new ShowStoryAction());
		Action.add(new ShowCommentAction());
		Action.add(new CreateCommentAction());
		Action.add(new DisplayGroupHomeAction());
		Action.add(new SearchInviteMemberAction());
		Action.add(new ShowInviteAction());
		Action.add(new InviteMemberAction());
		Action.add(new DisplayWorkoutAction());
		Action.add(new DeleteWorkoutAction());
		Action.add(new AddWorkoutAction());
		Action.add(new UpdateProfileAction());
		Action.add(new DisplayNotificationAction());
		Action.add(new AcceptInvitesAction());
		Action.add(new DeletePostAction());
		Action.add(new DeleteCommentAction());
		Action.add(new ImageAction());
		Action.add(new DisplayAddWorkoutAction());
		Action.add(new LogoutAction());
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doGet(request, response);
	}

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		String nextPage = performTheAction(request);
		sendToNextPage(nextPage, request, response);
	}

	/*
	 * Extracts the requested action and (depending on whether the user is
	 * logged in) perform it (or make the user login).
	 * 
	 * @param request
	 * 
	 * @return the next page (the view)
	 */
	private String performTheAction(HttpServletRequest request) {
		HttpSession session = request.getSession(true);
		String servletPath = request.getServletPath();
		User user = (User) session.getAttribute("user");
		String action = getActionName(servletPath);

		if (action.equals("register.do")) {
			return Action.perform(action, request);
		}

		if (action.equals("image.do")) {
			return Action.perform(action, request);
		}

		if (user == null && session.getAttribute("openid") == null) {
			// If the user hasn't logged in, so login is the only option
			return Action.perform("login.do", request);
		}

		if (action.equals("welcome")) {
			// User is logged in, but at the root of our web app
			return Action.perform("home.do", request);
		}

		// Let the logged in user run his chosen action
		return Action.perform(action, request);
	}

	/*
	 * If nextPage is null, send back 404 If nextPage ends with ".do", redirect
	 * to this page. If nextPage ends with ".jsp", dispatch (forward) to the
	 * page (the view) This is the common case
	 */
	private void sendToNextPage(String nextPage, HttpServletRequest request,
			HttpServletResponse response) throws IOException, ServletException {
		if (nextPage == null) {
			response.sendError(HttpServletResponse.SC_NOT_FOUND,
					request.getServletPath());
			return;
		}

		if (nextPage.charAt(0) == '/') {
			String host = request.getServerName();
			String port = ":" + String.valueOf(request.getServerPort());
			if (port.equals(":80"))
				port = "";
			response.sendRedirect("http://" + host + port + nextPage);
			return;
		}

		if (nextPage.charAt(0) == '/') {
			String host = request.getServerName();
			String port = ":" + String.valueOf(request.getServerPort());
			if (port.equals(":80"))
				port = "";
			response.sendRedirect("http://" + host + port + nextPage);
			return;
		}

		RequestDispatcher d = request.getRequestDispatcher("/" + nextPage);
		d.forward(request, response);
	}

	/*
	 * Returns the path component after the last slash removing any "extension"
	 * if present.
	 */
	private String getActionName(String path) {
		// We're guaranteed that the path will start with a slash
		int slash = path.lastIndexOf('/');
		return path.substring(slash + 1);
	}
}
